package com.dy.course.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.transaction.Transactional;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
import com.dy.course.common.BaseException;
import com.dy.course.common.BaseService;
import com.dy.course.common.Constant;
import com.dy.course.entity.CourseInfo;
import com.dy.course.entity.CourseSignInfo;
import com.dy.course.entity.UserBean;
import com.dy.course.enumerate.CourseStatus;
import com.dy.course.enumerate.CourseType;
import com.dy.course.mapper.CourseDetailMapper;
import com.dy.course.mapper.CourseMapper;
import com.dy.course.mapper.CourseSignMapper;
import com.dy.course.mapper.CourseTimeMapper;
import com.dy.course.mapper.CourseUserMapper;
import com.dy.course.mapper.CourseWeekMapper;
import com.dy.course.model.Course;
import com.dy.course.model.CourseDetail;
import com.dy.course.model.CourseSign;
import com.dy.course.model.CourseTime;
import com.dy.course.model.CourseUser;
import com.dy.course.model.CourseWeek;
import com.dy.course.service.ICycleCourseService;
import com.dy.course.util.DateUtil;

import tk.mybatis.mapper.entity.Example;

@Service
public class CycleCourseServcie extends BaseService<Course> implements ICycleCourseService {

	@Autowired
	private CourseWeekMapper courseWeekMapper;

	@Autowired
	private CourseTimeMapper courseTimeMapper;

	@Autowired
	private CourseNumTimeService numTimeService;

	@Autowired
	private CourseDetailMapper courseDetailMapper;

	@Autowired
	private CourseUserMapper courseUserMapper;

	@Autowired
	private CourseMapper courseMapper;

	@Autowired
	private CourseSignMapper courseSignMapper;

	@Override
	public List<CourseInfo> list(CourseInfo course) {
		logger.info("【查询周期性课程服务】参数信息:" + JSON.toJSONString(course));
		startPage(course);
		if (course.getType() == 1) {
			return courseMapper.selectCycleCourseUser(course);
		}
		return courseMapper.selectCycleCourseCreator(course);
	}

	@Transactional
	@Override
	public void createCourse(CourseInfo course) {
		/*
		 * @@@ 数据验证,业务验证 1.名称必填,非空,长度限制 2.图片id 3.地址必填 4.如果一次性课堂,那么time必填
		 * 5.老师id必填 6.roomId必填 7.开课院系必填 8.大学必填 9.type:必填 10.如何type=1,学期必填
		 * 11.如果type=1,start_th必填 12.如果type=1,end_th必填 13.如果type=1,week_day必填
		 * 14.如果type=1,first_day必填
		 * 
		 * 
		 */
		logger.info("【创建周期性课程服务】参数信息:" + JSON.toJSONString(course));

		// 插入课程详情
		Course insertCourse = new Course();
		BeanUtils.copyProperties(course, insertCourse);
		logger.info("插入周期性课程信息,参数信息:" + JSON.toJSONString(course));
		// course.setPictureId(Constant.DEFAULT_COURSE_PIC_ID);
		insertCourse.setCreateTime(DateUtil.now());
		int count = getMapper().insertSelective(insertCourse);
		if (count == 0) {
			logger.error("插入周期性课程失败,数据库异常,参数={}", JSON.toJSONString(insertCourse));
			throw new BaseException(Constant.Code.INSERT_ERROR, "插入课程失败,数据库异常", null);
		}
		Long courseId = insertCourse.getId();
		
		
		// 插入课程的周,例如:1-2 3-4 12 15
		List<CourseWeek> courseWeekList = course.getCourseWeekList();
		if(courseWeekList != null){
			for (CourseWeek ck : courseWeekList) {
				ck.setCourseId(courseId);
				ck.setUniversityId(insertCourse.getUniversityId());
				ck.setFacultyId(insertCourse.getFacultyId());
			}
			count = courseWeekMapper.batchInsert(courseWeekList);
			if (count < courseWeekList.size()) {
				logger.error("插入周期性课程上课周失败,数据库异常,参数={}", JSON.toJSONString(courseWeekList));
				throw new BaseException(Constant.Code.INSERT_ERROR, "插入周期性课程上课周失败,数据库异常", null);
			}
		}
		

		// 插入课程时间
		List<CourseTime> courseTimeList = course.getCourseTimeList();
		if(courseTimeList != null){
			for (CourseTime ct : courseTimeList) {
				ct.setCourseId(courseId);
				ct.setUniversityId(insertCourse.getUniversityId());
				ct.setFacultyId(insertCourse.getFacultyId());
			}
			count = courseTimeMapper.batchInsert(courseTimeList);
			if (count < courseTimeList.size()) {
				logger.error("插入课程时间失败,数据库异常,参数={}", JSON.toJSONString(courseTimeList));
				throw new BaseException(Constant.Code.INSERT_ERROR, "插入课程时间失败,数据库异常", null);
			}
		}
		

		
		// 哪一天
		// 第几节课
		// 什么时候
		// 插入第一条记录
		CourseDetail courseDetail = null;
		if(course.getType() == CourseType.CYCLE.getCode().byteValue()){
			// 生成要上的课程列表
			Date date = course.getFirstDay();
			// 一年的第几周
			int weekTh = DateUtil.getWeekOfYear(date);
			Date actDate = null;

			List<CourseDetail> courseDetailList = new ArrayList<CourseDetail>();
			for (CourseWeek ck : courseWeekList) {
				// 开始周
				int startWeek = ck.getStartWeek();
				// 结束周
				int endWeek = ck.getEndWeek();
				for (int th = startWeek; th <= endWeek; th++) {

					int actWeek = weekTh + th - 1;
					int actYear = DateUtil.getDateYear(date);
					// 对每一天而言
					for (CourseTime ct : courseTimeList) {
						actDate = DateUtil.getYearByWeekAndWeekend(actYear, actWeek, ct.getWeekDay());
						// 对每一次课而言
						courseDetail = new CourseDetail();
						courseDetail.setCourseId(courseId);
						courseDetail.setRoomId(insertCourse.getRoomId());
						courseDetail.setActStartTime(DateUtil.mergeDate(actDate, numTimeService
								.getByKey(actDate, insertCourse.getUniversityId(), ct.getStartTh()).getStartTime()));
						courseDetail.setActEndTime(DateUtil.mergeDate(actDate, numTimeService
								.getByKey(actDate, insertCourse.getUniversityId(), ct.getEndTh()).getEndTime()));
						courseDetail.setUniversityId(insertCourse.getUniversityId());
						courseDetail.setSignWay(insertCourse.getSignWay());
						courseDetail.setFacultyId(insertCourse.getFacultyId());
						courseDetail.setWeekDay(ct.getWeekDay());
						courseDetail.setStartTh(ct.getStartTh());
						courseDetail.setStatus(CourseStatus.NEW.getCode().byteValue());
						courseDetail.setEndTh(ct.getEndTh());
						courseDetailList.add(courseDetail);
					}
				}
			}
			count = courseDetailMapper.batchInsert(courseDetailList);
			if (count < courseDetailList.size()) {
				logger.error("批量生产课程失败,数据库异常,参数={}", JSON.toJSONString(courseTimeList));
				throw new BaseException(Constant.Code.INSERT_ERROR, "批量生产课程失败,数据库异常", null);
			}
		}else{
			courseDetail = new CourseDetail();
			courseDetail.setCourseId(courseId);
			courseDetail.setRoomId(insertCourse.getRoomId());
			courseDetail.setActStartTime(DateUtil.mergeDate(course.getStartTime(), numTimeService
					.getByKey(course.getStartTime(), insertCourse.getUniversityId(), course.getStartTh()).getStartTime()));
			courseDetail.setActEndTime(DateUtil.mergeDate(course.getStartTime(), numTimeService
					.getByKey(course.getStartTime(), insertCourse.getUniversityId(), course.getEndTh()).getEndTime()));
			courseDetail.setUniversityId(insertCourse.getUniversityId());
			courseDetail.setSignWay(insertCourse.getSignWay());
			courseDetail.setFacultyId(insertCourse.getFacultyId());
			courseDetail.setWeekDay(DateUtil.getDayOfWeek(course.getStartTime()));
			courseDetail.setStartTh(course.getStartTh());
			courseDetail.setStatus(CourseStatus.NEW.getCode().byteValue());
			courseDetail.setEndTh(course.getEndTh());
			count = courseDetailMapper.insertSelective(courseDetail);
			if (count < 1) {
				logger.error("【】插入临时课程失败,参数={}", JSON.toJSONString(courseDetail));
				throw new BaseException(Constant.Code.INSERT_ERROR, "插入临时课程失败,数据库异常", null);
			}
		}
		

		// 插入用户列表
		List<Long> userList = course.getUserList();
		List<CourseUser> courseUserList = new ArrayList<CourseUser>();
		for (Long userId : userList) {
			CourseUser cu = new CourseUser();
			cu.setUserId(userId);
			cu.setCourseId(insertCourse.getId());
			cu.setUniversityId(insertCourse.getUniversityId());
			cu.setFacultyId(insertCourse.getFacultyId());
			courseUserList.add(cu);
		}
		count = courseUserMapper.batchInsert(courseUserList);
		if (count < courseUserList.size()) {
			logger.error("插入课程用户失败,数据库异常,参数={}", JSON.toJSONString(courseTimeList));
			throw new BaseException(Constant.Code.INSERT_ERROR, "插入课程用户失败,数据库异常", null);
		}
	}

	@Override
	public void sign(CourseSignInfo csi) {
		logger.info("【周期性课堂签到】参数={csi}", JSON.toJSONString(csi));

		// 课程是否已经开始
		CourseDetail courseDetail = courseDetailMapper.selectByPrimaryKey(csi.getCourseDetailId());
		if (courseDetail == null) {
			logger.error("【】数据已经被删除或者不存在" + JSON.toJSONString(courseDetail));
			throw new BaseException(Constant.Code.SELECT_ERROR, "数据已经被删除或者不存在", null);
		}

		//###这里待定,什么时候开始签到,可以通过status或者加一个字段来标识
		if ( courseDetail.getStatus() != CourseStatus.NEW.getCode().byteValue()) {
			logger.error("【】'已创建'状态的课堂才能进行签到,课堂信息=" + JSON.toJSONString(courseDetail));
			throw new BaseException(Constant.Code.COURSE_STATUS_ERROR,
					CourseStatus.getDesc(courseDetail.getStatus().intValue()) + "状态的课程不能进行签到", null);
		}

		//查询这堂课哪些人应该签到
		boolean isIn = false;
		List<UserBean> userList = courseDetailMapper.selectCycleCourseUserSign(csi);
		for (UserBean user : userList) {
			if (user.getId().equals(csi.getUserId())) {
				isIn = true;
			}
		}
		if (!isIn) {
			logger.error("【】没有家加入课程的不能签到");
			throw new BaseException(Constant.Code.COURSE_NOT_JOIN, "没有加入课程的不能签到", null);
		}

		// 已经签到的不能再进行签到
		CourseSign courseSign = new CourseSign();
		courseSign.setCourseId(csi.getCourseDetailId());
		courseSign.setUserId(csi.getUserId());
		int isSign = courseSignMapper.selectCount(courseSign);
		if (isSign > 0) {
			logger.error("【】已经签到");
			throw new BaseException(Constant.Code.ALREADY_SIGN, "已经签到", null);
		}

		// 签到的mck不能重复
		Example example = new Example(CourseSign.class);
		example.createCriteria()
				.andCondition("course_id=" + csi.getCourseDetailId() + " and mck='" + csi.getMck() + "'");
		List<CourseSign> list = courseSignMapper.selectByExample(example);
		if (list.size() >= 1) {
			logger.error("【】课程mck重复不可签到:list=" + JSON.toJSONString(list) + ",csi=" + list.get(0));
			throw new BaseException(Constant.Code.ALREADY_SIGN, "mck不可重复签到", null);
		}

		// 插入签到信息
		CourseSign insertCourseSign = new CourseSign();
		BeanUtils.copyProperties(csi, insertCourseSign);
		insertCourseSign.setTime(new Date());
		insertCourseSign.setCourseId(csi.getCourseDetailId());
		// insertMeetingSign.setStatus(SignStatus.SIGNED.getCode().byteValue());
		logger.info("【】课程签到服务,参数信息:msi=" + insertCourseSign);
		int count = courseSignMapper.insert(insertCourseSign);
		if (count != 1) {
			logger.error("【】数据库异常");
			throw new BaseException(Constant.Code.INSERT_ERROR, "数据库异常", null);
		}

	}


	@Override
	public List<CourseSignInfo> selectCycleCourseMembers(CourseSignInfo cb) {
		logger.info("【周期课程成员查询】,参数信息:cb=" + JSON.toJSONString(cb));
		return courseUserMapper.selectCycleCourseMember(cb);
	}

	@Transactional
	@Override
	public void deleteOne(CourseInfo course) {
		logger.info("【删除课堂服务】,参数信息:cb=" + JSON.toJSONString(course));
		CourseDetail detail = courseDetailMapper.selectByPrimaryKey(course.getCourseDetailId());
		if(detail == null){
			logger.error("【】数据库异常,数据已经被删除或者不存在,courseDetailId={}",course.getCourseDetailId());
			throw new BaseException(Constant.Code.DELETE_ERROR, "数据库异常,数据被删除或者不存在", null);
		}
		/*if(detail.getStatus() != CourseStatus.NEW.getCode().byteValue()){
			logger.error("【】只有新建的课程可以删除,detail={}",JSON.toJSONString(detail));
			throw new BaseException(Constant.Code.COURSE_STATUS_ERROR, "只有新建的课程可以删除", null);
		}*/
		int count = courseDetailMapper.deleteByPrimaryKey(course.getCourseDetailId());
		if(count < 1){
			logger.error("【】删除具体课程失败,detail={}",JSON.toJSONString(detail));
			throw new BaseException(Constant.Code.DELETE_ERROR, "数据库异常,数据被删除或者不存在", null);
		}
		
		
		//课程签到信息删除
		Example example = new Example(CourseSign.class);
		example.createCriteria().andEqualTo("courseId", course.getId());
		courseSignMapper.deleteByExample(example);
		
		
//		if(course.getCourseType() == CourseType.TEMPORARY.getCode().byteValue()){
//			logger.info("【】删除临时课程模板,course={}",JSON.toJSONString(course));
//			count = courseMapper.deleteByPrimaryKey(course.getId());
//			if(count < 1){
//				logger.error("【】删除临时课程模板程失败,course={}",JSON.toJSONString(course));
//				throw new BaseException(Constant.Code.DELETE_ERROR, "数据库异常,数据被删除或者不存在", null);
//			}
//		}
		
	}

	
	@Transactional
	@Override
	public void deleteCourseTemplate(CourseInfo course) {
		logger.info("【删除课堂模板服务】,参数信息:cb=" + JSON.toJSONString(course));
		Course template = courseMapper.selectByPrimaryKey(course.getId());
		if(template == null){
			logger.error("【】数据库异常,数据已经被删除或者不存在,id={}",course.getId());
			throw new BaseException(Constant.Code.DELETE_ERROR, "数据库异常,数据被删除或者不存在", null);
		}
		
		//删除课堂模板
		Example example = new Example(Course.class);
		example.createCriteria().andEqualTo("id", course.getId());
	    int count = courseMapper.deleteByExample(example);
	    if(count < 1){
	    	logger.error("【】数据库异常,数据不存在或者完整,id={}",course.getId());
			throw new BaseException(Constant.Code.DELETE_ERROR, "数据库异常,数据不存在或者不完整", null);
	    }
	    
		//删除用户信息
		example = new Example(CourseUser.class);
		example.createCriteria().andEqualTo("courseId", template.getId());
	    courseUserMapper.deleteByExample(example);
	    
	    //删除课程信息,课程用户信息,课程签到信息
	    example = new Example(CourseDetail.class);
		example.createCriteria().andEqualTo("courseId", course.getId());
	    List<CourseDetail> detailList = courseDetailMapper.selectByExample(example);
	    CourseInfo ci = new CourseInfo();
	    for(CourseDetail detail:detailList){
	    	ci.setCourseDetailId(detail.getId());
	    	deleteOne(ci);
	    }
	    
	    //删除课程时间信息
		example = new Example(CourseTime.class);
		example.createCriteria().andEqualTo("courseId", course.getId());
		count = courseTimeMapper.deleteByExample(example);
		if(count < 1){
			logger.error("【】删除课程时间信息失败,group={}",JSON.toJSONString(course));
			throw new BaseException(Constant.Code.DELETE_ERROR, "数据库异常,数据被删除或者不存在", null);
		}
		
		//删除课程周信息
		example = new Example(CourseWeek.class);
		example.createCriteria().andEqualTo("courseId", course.getId());
		count = courseWeekMapper.deleteByExample(example);
		if(count < 1){
			logger.error("【】删除课程周信息失败,group={}",JSON.toJSONString(course));
			throw new BaseException(Constant.Code.DELETE_ERROR, "数据库异常,数据被删除或者不存在", null);
		}
	}

	@Override
	public CourseInfo getCourseTemplate(CourseInfo course) {
		logger.info("【获取课程模板服务】,参数信息:course=" + JSON.toJSONString(course));
		CourseInfo courseInfo = this.courseMapper.selectTemplate(course.getId());
		if(courseInfo == null){
			logger.error("【】数据库异常,数据不存在或者完整,id={}",course.getId());
			throw new BaseException(Constant.Code.SELECT_ERROR, "数据库异常,数据不存在或者不完整", null);
		}
		return courseInfo;
	}

	@Override
	public List<CourseInfo> selectTemplate(CourseInfo course) {
		logger.info("【查询课程模板服务】,参数信息:course=" + JSON.toJSONString(course));
		return null;
	}

	@Override
	public List<CourseInfo> getTemplateDetail(CourseInfo course) {
		return null;
	}

	@Override
	public void rebuildCourse(CourseInfo course) {
	}

	@Override
	public void updateCourse(CourseInfo course) {
		logger.info("【更新课程服务】,参数信息:course=" + JSON.toJSONString(course));
	}

	@Override
	public Integer getCourseNum(Long universityId) {
		return (Integer) this.redisCache.get(Constant.CacheKey.COURSE_MAX_NUM+"#"+universityId);
	}
}
